﻿using Brc_PaaS.Bll.System;
using Brc_PaaS.Common.Entity;
using Brc_PaaS.Common.Model.Basic;
using Brc_PaaS.Common.Model.RabbitMq;
using Brc_PaaS.Core.RabbitMq;
using Brc_PaaS.Dal;
using Exceptionless;
using Exceptionless.Logging;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Brc_PaaS.Bll.RabbitMq
{
    public class RabbitMqBasicManager : IRabbitMqBasicManager
    {
        private readonly IConfiguration configuration;
        private readonly ISystem system;
        private readonly IRabbitMqBasic rabbitMqBasic;
        private readonly IRepository<Ass_RabbitMq> rabbitMqRepository;
        string loginUserName = "";
        string loginPassword = "";
        string requestUrl = "";
        string initPassword = "";
        public RabbitMqBasicManager(IConfiguration configuration, ISystem system, IRabbitMqBasic rabbitMqBasic, IRepository<Ass_RabbitMq> rabbitMqRepository)
        {
            this.configuration = configuration;
            this.system = system;
            this.rabbitMqBasic = rabbitMqBasic;
            this.rabbitMqRepository = rabbitMqRepository;
            initConfig();
        }

        void initConfig()
        {
            loginUserName = configuration.GetValue<string>("RabbitMqLoginUserName");
            loginPassword = configuration.GetValue<string>("RabbitMqLoginPassword");
            requestUrl = configuration.GetValue<string>("RabbitMqRequestUrl");
            initPassword = configuration.GetValue<string>("RabbitMqInitUserPwd");
        }


        public ResponseModel<RabbitMqBasicInfoDto> CreateRabbitMq(string systemId, string createUserId)
        {
            var result = new ResponseModel<RabbitMqBasicInfoDto>() { IsSuccess = false };
            var systemInfo = system.GetSystem(systemId);
            if (systemInfo == null || !systemInfo.IsSuccess || systemInfo.Data == null)
            {
                result.Msg = "未找到系统信息";
                return result;
            }
            var createUserResult = CreateUser(systemInfo.Data, createUserId);
            if (createUserResult != null && createUserResult.IsSuccess)
            {
                var crateHostResult = CreateHost(systemInfo.Data);
                if (crateHostResult != null && crateHostResult.IsSuccess)
                {
                    var allocatePermissionResult = AllocatePermission(systemInfo.Data);
                    if (allocatePermissionResult != null && allocatePermissionResult.IsSuccess)
                    {
                        result.IsSuccess = true;
                        return result;

                    }
                    else
                    {
                        DeleteHost(systemInfo.Data);
                        DeleteUser(systemInfo.Data);

                        result.Msg = allocatePermissionResult?.Msg;
                        return result;
                    }
                   
                }
                else
                {
                    DeleteUser(systemInfo.Data);

                    result.Msg = crateHostResult.Msg;
                    return result;
                }
            }
            else
            {
                result.Msg = createUserResult.Msg;
                return result;
            }

            
        }
        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="systemInfo"></param>
        /// <param name="createUserId"></param>
        /// <returns></returns>
        public BaseResponseModel CreateUser(Bas_System systemInfo, string createUserId)
        {
            var result = new BaseResponseModel() { IsSuccess = false };
            var rabbitMqInfoResult = GetRabbitMqBySystemId(systemInfo.Id);

            if(rabbitMqInfoResult!=null && rabbitMqInfoResult.IsSuccess&& rabbitMqInfoResult.Data!=null)
            {
                result.Msg = "该系统已存在RabbitMq,不能再创建";
                return result;
            }

            var requestCreateUserDto = new RabbitMqCreateUserDto()
            {
                LoginUserName = loginUserName,
                LoginPassword = loginPassword,
                RequestUrl = requestUrl,
                UserName = systemInfo.Name,
                Password = initPassword,
                Tags= "administrator"
            };
            var createUserResult = rabbitMqBasic.CreateUser(requestCreateUserDto);
            if (createUserResult.IsSuccess)
            {
                var rabbitMqItem = new Ass_RabbitMq
                {
                    Id = Guid.NewGuid().ToString("N"),
                    CreateTime = DateTime.Now,
                    CreateUserId = createUserId,
                    Password = initPassword,
                    SystemId = systemInfo.Id,
                    UserName = systemInfo.Name,
                };
                var affectNumber = rabbitMqRepository.AddItem(rabbitMqItem);
                if (affectNumber <= 0)
                {
                    WriteLog("CreateUser", systemInfo.Name, systemInfo.Id, "创建用户", "添加到数据库失败", JsonConvert.SerializeObject(rabbitMqItem));
                    result.Msg = "添加数据库失败";
                    return result;
                }
                result.IsSuccess = true;
                return result;
            }
            else
            {
                WriteLog("CreateUser", systemInfo.Name, systemInfo.Id, "创建用户", "请求RabbitMq创建用户失败", createUserResult.Msg);
                return result;
            }

        }

        public BaseResponseModel DeleteUser(Bas_System systemInfo)
        {
            var result = new BaseResponseModel() { IsSuccess = false };
            var requestCreateUserDto = new RabbitMqBasicRequestDto()
            {
                LoginUserName = loginUserName,
                LoginPassword = loginPassword,
                RequestUrl = requestUrl,
            };
            var createUserResult = rabbitMqBasic.DeleteUser(systemInfo.Name, requestCreateUserDto);
            if (createUserResult.IsSuccess)
            {

                var affectNumber = rabbitMqRepository.Delete(x => systemInfo.Name == x.UserName);
                if (affectNumber <= 0)
                {
                    WriteLog("DeleteUser", systemInfo.Name, systemInfo.Id, "删除用户", "删除用户失败", systemInfo.Name);
                    result.Msg = "删除用户失败";
                    return result;
                }
                result.IsSuccess = true;
                return result;
            }
            else
            {
                WriteLog("DeleteUser", systemInfo.Name, systemInfo.Id, "删除用户", "请求RabbitMq删除用户失败", createUserResult.Msg);
                return result;
            }
        }

        public BaseResponseModel CreateHost(Bas_System systemInfo)
        {
            var result = new BaseResponseModel() { IsSuccess = false };
            var virtualHostName = systemInfo.Name + "_vh";
            var virtualHost = new RabbitMqCreateVitrualHostDto()
            {

                LoginPassword = initPassword,
                LoginUserName = systemInfo.Name,
                RequestUrl = requestUrl,
                VirtualHostName = virtualHostName
            };
            var crateVirtualHostResult = rabbitMqBasic.CreateVirtualHost(virtualHost);
            if (crateVirtualHostResult.IsSuccess)
            {
                var rabbitMqDetailResult = GetRabbitMqBySystemId(systemInfo.Id);
                if (rabbitMqDetailResult == null || !rabbitMqDetailResult.IsSuccess || rabbitMqDetailResult.Data == null)
                {
                    result.Msg = "未找到RabbitMq的信息";
                    return result;
                }
                var rabbitMqItem = rabbitMqDetailResult.Data;
                rabbitMqItem.VirtualHost = virtualHostName;
                var affectNumber = rabbitMqRepository.Update(rabbitMqItem);
                if (affectNumber <= 0)
                {
                    WriteLog("CreateHost", systemInfo.Name, systemInfo.Id, "创建虚拟Host", "修改VirtualHost到数据库失败", JsonConvert.SerializeObject(rabbitMqItem));
                    result.Msg = "修改VirtualHost到数据库失败";
                    return result;
                }
                result.IsSuccess = true;
                return result;
            }
            else
            {
                WriteLog("CreateHost", systemInfo.Name, systemInfo.Id, "创建VirtualHost", "请求RabbitMq创建VirtualHost失败", crateVirtualHostResult.Msg);
                return result;
            }
        }

        public BaseResponseModel DeleteHost(Bas_System systemInfo)
        {
            var result = new BaseResponseModel() { IsSuccess = false };
            var virtualHostName = systemInfo.Name + "_vh";
            var virtualHost = new RabbitMqBasicRequestDto()
            {

                LoginPassword = loginPassword,
                LoginUserName = loginUserName,
                RequestUrl = requestUrl
               
            };
            var crateVirtualHostResult = rabbitMqBasic.DeleteVirtualHost(virtualHostName,virtualHost);
            if (crateVirtualHostResult.IsSuccess)
            {
                var rabbitMqDetailResult = GetRabbitMqBySystemId(systemInfo.Id);
                if (rabbitMqDetailResult == null || !rabbitMqDetailResult.IsSuccess || rabbitMqDetailResult.Data == null)
                {
                    result.Msg = "未找到RabbitMq的信息";
                    return result;
                }
                var rabbitMqItem = rabbitMqDetailResult.Data;
                rabbitMqItem.VirtualHost = null;
                var affectNumber = rabbitMqRepository.Update(rabbitMqItem);
                if (affectNumber <= 0)
                {
                    WriteLog("DeleteHost", systemInfo.Name, systemInfo.Id, "修改虚拟Host", "修改VirtualHost到数据库失败", JsonConvert.SerializeObject(rabbitMqItem));
                    result.Msg = "修改VirtualHost到数据库失败";
                    return result;
                }
                result.IsSuccess = true;
                return result;
            }
            else
            {
                WriteLog("DeleteHost", systemInfo.Name, systemInfo.Id, "删除VirtualHost", "请求RabbitMq删除VirtualHost失败", crateVirtualHostResult.Msg);
                return result;
            }
        }

        public BaseResponseModel AllocatePermission(Bas_System systemInfo)
        {
            var result = new BaseResponseModel() { IsSuccess = false };
            var permission = new RabbitMqVirtualHostPermissionDto
            {
                Configure = ".*",
                Read = ".*",
                Write = ".*"
            };
            var virtualHostName = systemInfo.Name + "_vh";
            var virtualHost = new RabbitMqAllocatePermissionDto()
            {
                LoginPassword = loginPassword,
                LoginUserName = loginUserName,
                RequestUrl = requestUrl,
                VirtualHostName = virtualHostName,
                UserName =systemInfo.Name,
                Permission = permission
            };
            var crateVirtualHostResult = rabbitMqBasic.AllocatePermission(virtualHost);
            if (crateVirtualHostResult.IsSuccess)
            {
                var rabbitMqDetailResult = GetRabbitMqBySystemId(systemInfo.Id);
                if (rabbitMqDetailResult == null || !rabbitMqDetailResult.IsSuccess || rabbitMqDetailResult.Data == null)
                {
                    result.Msg = "未找到RabbitMq的信息";
                    return result;
                }
                var rabbitMqItem = rabbitMqDetailResult.Data;
                rabbitMqItem.VirtualHostPermissions = JsonConvert.SerializeObject(permission);
                var affectNumber = rabbitMqRepository.Update(rabbitMqItem);
                if (affectNumber <= 0)
                {
                    WriteLog("AllocatePermission", systemInfo.Name, systemInfo.Id, "分配权限", "修改RabbitMq权限失败", JsonConvert.SerializeObject(rabbitMqItem));
                    result.Msg = "修改RabbitMq权限失败";
                    return result;
                }
                result.IsSuccess = true;
                return result;

            }
            return result;
        }

        public ResponseModel<Ass_RabbitMq> GetRabbitMqBySystemId(string systemId)
        {
            var result = new ResponseModel<Ass_RabbitMq>() { IsSuccess = false };
            if (string.IsNullOrWhiteSpace(systemId))
            {
                result.Msg = "systemId不能为空";


                return result;
            }
            result.Data = rabbitMqRepository.GetList(i => i.SystemId == systemId).FirstOrDefault(); ;
            result.IsSuccess = true;
            return result;
        }

        private void WriteLog(string method, string systemName, string systemId, string failureHead, string failureReason, string parameters = "")
        {
            Task.Run(() =>
            {
                ExceptionlessClient.Default.CreateLog("Brc_PaaS.Bll.RabbitMq." + method, $"业务系统：{systemName}(系统Id为【{systemId}】)，于【{DateTime.Now.ToString("s")}】{failureHead}失败。失败原因：【{failureReason}】" + (string.IsNullOrWhiteSpace(parameters) ? "" : ("参数为：" + parameters)), LogLevel.Error).Submit();
            });
        }
    }
}
